class Produto < ActiveRecord::Base

    named_scope :aprovados, :conditions => ['direito_negado IS NULL OR direito_negado = ?', false]

    default_scope :order => :descricao

    with_options :readonly => true do |p|
      p.belongs_to :unidade_medida
      p.belongs_to :setor_economico
    end

    delegate :descricao_abreviada, :instrumento_legal, :to => :setor_economico, :prefix => :setor, :allow_nil => true

    has_many :producoes, :dependent => :destroy, :foreign_key=> 'produto_id' do
      def ano_mais_recente
        maximum(:ano)
      end
      def ano_mais_antigo
        minimum(:ano)
      end
      def mes_mais_antigo(ano = nil)
        minimum(:mes, :conditions => {:ano => ano}) || 1
      end
      def mes_mais_recente(ano = nil)
        maximum(:mes, :conditions => {:ano => ano}) || 12
      end
      def get(range = Time.now.year-4..Time.now.year)
        all(:conditions => {:ano => range})
      end
      def total_anual(ano)
        sum(:quantidade_produzida , :conditions => {:ano => ano}) || 0
      end
      def indice_anual(ano, ano_proporcional = ano_mais_recente)
        pe = total_anual(ano)
        return 0 if pe == 0
        cri = proxy_owner.capacidade_real_instalada
        cria = proxy_owner.ampliacao_ou_mod_parcial? ? proxy_owner.capacidade_real_instalada_anterior : 0
        proporcional = ano == ano_proporcional
        mes = proporcional ? total_meses_validos(ano) : 12
        indice = ((pe - cria) * 1200.0) / ((cri - cria) * mes)
        return indice, proporcional
      end
      def total_meses_validos(ano)
        mes_mais_recente(ano) - (ano_mais_recente == ano_mais_antigo ? mes_mais_antigo(ano) - 1 : 0)
      end
    end

    belongs_to :atividade

    # Validations
    validates_presence_of     :atividade, :descricao, :unidade_medida
    validates_numericality_of :capacidade_real_instalada, :greater_than => 0
    validates_presence_of     :data_operacional, :if => :reducao_fixa?
    validates_presence_of     :producao_efetiva_anual, :if => :reducao_escalonada?
    validates_numericality_of :producao_efetiva_anual, :if => :reducao_escalonada?
    validates_presence_of     :capacidade_real_instalada_anterior, :if => :ampliacao_ou_mod_parcial?
    validates_numericality_of :capacidade_real_instalada_anterior, :greater_than => 0, :allow_nil => true

    validate :aumento_maior_que_ampliacao_minima, :producao_efetiva_anual_ate_capacidade_real_instalada

    def aumento_maior_que_ampliacao_minima
      if ampliacao_ou_mod_parcial?
        minimo = atividade.caracterizacao.ampliacao_minima
        if aumento_capacidade_instalada < minimo
          errors.add_to_base "Aumento da Capacidade Real Instalada deve ser no mínimo #{minimo}%"
        end
      end
    end

    def producao_efetiva_anual_ate_capacidade_real_instalada
      if reducao_escalonada? && capacidade_real_instalada < producao_efetiva_anual
        errors.add_to_base "Produção Efetiva Anual deve ser menor ou igual à Capacidade Real Instalada"
      end
    end

    # Helpers
    def aumento_capacidade_instalada
      capacidade_real_instalada_anterior ? (aumento_capacidade_instalada_abs * 100.0 / capacidade_real_instalada_anterior) : 0
    end

    def aumento_capacidade_instalada_abs
      capacidade_real_instalada - capacidade_real_instalada_anterior if capacidade_real_instalada_anterior
    end

    # FIXME usar delegate
    def tipo_projeto
      atividade.caracterizacao.tipo_projeto
    end

    def enquadramento
      self[:enquadramento] || setor_descricao_abreviada
    end

    def reducao_fixa?
      atividade.caracterizacao.pleito.reducao_fixa?
    end

    def reducao_escalonada?
      atividade.caracterizacao.pleito.reducao_escalonada?
    end

    def ampliacao_ou_mod_parcial?
      atividade.caracterizacao.ampliacao_ou_mod_parcial?
    end

    def alcanca?(indice)
      indice >= 20
    end

    def alcanca_indice?(ano, ano_proporcional = producoes.ano_mais_recente)
      indice, proporcional = producoes.indice_anual(ano, ano_proporcional)
      alcanca?(indice)
    end

    def detalhes_producao
      calcular_detalhes_producao unless defined?(@detalhes_producao)
      @detalhes_producao
    end

    def atende_condicao?
      calcular_detalhes_producao unless defined?(@atende_condicao)
      @atende_condicao
    end

    def detalhes_producao_fxml
      detalhes_producao.to_fxml(:skip_instruct => true).gsub(/</, '¨@¨').gsub(/>/, '¨#¨')
    end

    def condicao_atendida
      @atende_condicao
    end

    # primeiro ano em que alcançou o índice
    def ano_entrou_operacao
      ano_base = producoes.ano_mais_antigo
      return false unless ano_base

      ano_proporcional = ano_base+3
      ano_base.upto(ano_proporcional) do |ano|
        return ano if alcanca_indice?(ano, ano_proporcional)
      end

      false
    end

    # quantos anos poderá gozar do benefício
    def prazo_vigencia
      [APP_CONFIG["vigencia_red_75"], APP_CONFIG["ano_fim_red_75"] - Date.current.year.pred].min
    end

    def ano_laudo
      self.atividade.caracterizacao.pleito.data_laudo.try(:year) || Date.current.year
    end

    def fruicao
      ano_operacao = ano_entrou_operacao
      vigencia     = prazo_vigencia

      ano_inicio   = ano_laudo
      ano_inicio  += 1 if (ano_operacao == ano_inicio)
      data_inicio  = Date.new(ano_inicio)
      data_fim     = data_inicio + vigencia.years - 1.day
      periodo      = data_inicio..data_fim

      if block_given?
        yield periodo, ano_operacao, vigencia
      else
        {:periodo => periodo, :ano_operacao => ano_operacao, :vigencia => vigencia}
      end
    end

    def registrar_analise(params)
      self.update_attributes({
        :descricao_analista => params[:descricao],
        :enquadramento      => params[:enquadramento],
        :setor_economico_id => params[:setor_id],
        :analise_direito    => params[:analise_direito],
        :direito_negado     => params[:direito_negado],
        :obs_vistoria       => params[:obs_vistoria]
      })
    end

  private

    # calcula detalhes da produção nos últimos 4 anos declarados
    def calcular_detalhes_producao
      @detalhes_producao, @atende_condicao = [], false

      ano_base = producoes.ano_mais_recente
      return unless ano_base

      ano_base.downto(ano_base-4) do |ano|
        producao_efetiva = producoes.total_anual(ano)
        next if producao_efetiva == 0
        indice, proporcional = producoes.indice_anual(ano, ano_base)
        @detalhes_producao << {
          :ano              => ano,
          :mes_comeco       => 1,
          :mes_fim          => 12,
          :producao_efetiva => producao_efetiva,
          :indice           => indice,
          :proporcional     => proporcional,
          :alcancado        => alcanca?(indice)
        }
      end

      @detalhes_producao.first[:mes_fim]   = producoes.mes_mais_recente(@detalhes_producao.first[:ano])
      @detalhes_producao.last[:mes_comeco] = producoes.mes_mais_antigo(@detalhes_producao.last[:ano])
      @atende_condicao                     = @detalhes_producao.any? {|p| p[:alcancado]}
    end

end
